package store

import (
	"fmt"
	"log-record/utils"
	"net/url"
	"strconv"
	"time"
)

func init() {
	hasTable := DB.Migrator().HasTable(&RemoteLog{})
	if !hasTable {
		err := DB.Migrator().CreateTable(&RemoteLog{})
		if err != nil {
			fmt.Println(err)
		}
	}
	hasTable = DB.Migrator().HasTable(&User{})

	if !hasTable {
		err := DB.Migrator().CreateTable(&User{})
		if err != nil {
			fmt.Println(err)
		}
	}
}

type RemoteLog struct {
	// ID 自增ID
	Id uint64 `gorm:"primaryKey;type:int(20) AUTO_INCREMENT;comment:主键" json:"id"`
	// Application 应用标识
	Application string `gorm:"index;type:varchar(20);comment:应用标识" json:"application"`
	// Timestamp 时间戳，日志创建时间
	Timestamp int64 `gorm:"type:bigint(22);comment:时间戳，日志创建时间" json:"timestamp"`
	// LoggerName 日志名
	LoggerName string `gorm:"column:logger_name;type:varchar(100);comment:日志名" json:"loggerName"`
	// Level 日志级别
	Level string `gorm:"index;type:varchar(10);comment:日志级别" json:"level"`
	// Message 日志消息
	Message string `gorm:"type:text;comment:日志消息" json:"message"`
	//Address 客户端ip
	Address string `gorm:"type:varchar(20);comment:客户端ip" json:"address"`
	// Thread 线程
	Thread string `gorm:"type:varchar(40);comment:线程" json:"thread"`
	// LinkId 链路id，有则存在
	LinkId string `gorm:"column:link_id;index;type:varchar(40);default:'';comment:链路id，有则存在" json:"linkId"`
	// LinkCounter 链路自增器，保证链路有序
	LinkCounter string `gorm:"column:link_counter;type:int(5);default:0;comment:链路自增器，保证链路有序" json:"linkCounter"`
	// Metadata 其他元数据信息
	Metadata string `gorm:"type:text;comment:其他元数据信息" json:"metadata"`
}

func (RemoteLog) TableName() string {
	return "t_remote_log"
}

//QueryAllApplication 查询所有应用
func (log *RemoteLog) QueryAllApplication() []string {
	var applications []string
	DB.Model(log).Select("application").Group("application").Find(&applications)
	return applications
}

//QueryLogs 多条件查询日志
func (log *RemoteLog) QueryLogs(values url.Values) ([]RemoteLog, int64) {
	page := utils.GetOrderDefault(values, "page", 1, func(str string) (int, error) {
		return strconv.Atoi(str)
	})
	size := utils.GetOrderDefault(values, "size", 10, func(str string) (int, error) {
		return strconv.Atoi(str)
	})
	if size <= 0 {
		size = 10
	}
	if page <= 0 {
		page = 1
	}
	var remoteLogs []RemoteLog
	db := DB.Offset(page - 1).Limit(size)
	if values.Has("startTime") && values.Has("endTime") {
		startTime := utils.GetOrderDefault(values, "startTime", 0, func(str string) (int, error) {
			return strconv.Atoi(str)
		})
		endTime := utils.GetOrderDefault(values, "endTime", 0, func(str string) (int, error) {
			return strconv.Atoi(str)
		})
		db = db.Where("timestamp BETWEEN ? AND ?", startTime, endTime)
	} else if values.Has("startTime") && !values.Has("endTime") {
		startTime := utils.GetOrderDefault(values, "startTime", 0, func(str string) (int, error) {
			return strconv.Atoi(str)
		})
		db = db.Where("timestamp >= ?", startTime)
	} else if !values.Has("startTime") && values.Has("endTime") {
		endTime := utils.GetOrderDefault(values, "endTime", 0, func(str string) (int, error) {
			return strconv.Atoi(str)
		})
		db = db.Where("timestamp <= ?", endTime)
	}
	utils.IfPresent(values, "app", func(value string) {
		db = db.Where("application = ?", value)
	})

	utils.IfPresent(values, "ip", func(value string) {
		db = db.Where("address = ?", value)
	})

	utils.IfPresent(values, "level", func(value string) {
		db = db.Where("level = ?", value)
	})

	var count int64
	db.Order("id ASC").Find(&remoteLogs)
	db.Count(&count)
	return remoteLogs, count
}

//QueryAllLevel 查询所有日志的级别
func (log *RemoteLog) QueryAllLevel(values url.Values) []string {
	var level []string
	db := DB.Model(log).Select("level").Group("level")
	utils.IfPresent(values, "app", func(value string) {
		db = db.Where("application = ?", value)
	})
	utils.IfPresent(values, "ip", func(value string) {
		db = db.Where("address = ?", value)
	})
	db.Find(&level)
	return level
}

//QueryAllIp 查询所有日志的ip
func (log *RemoteLog) QueryAllIp(values url.Values) []string {
	var addresses []string
	db := DB.Model(log).Select("address").Group("address")
	utils.IfPresent(values, "app", func(value string) {
		db = db.Where("application = ?", value)
	})
	db.Find(&addresses)
	return addresses
}

type User struct {
	// ID 自增ID
	Id         uint64    `gorm:"primaryKey;type:int(20) AUTO_INCREMENT;comment:'主键'" json:"id"`
	Username   string    `gorm:"type:varchar(20) NOT NULL;comment:用户名" json:"username"`
	Password   string    `gorm:"type:varchar(40) NOT NULL;comment:密码" json:"password"`
	CreateTime time.Time `gorm:"type:datetime;comment:创建时间" json:"create_time"`
}

func (User) TableName() string {
	return "t_user"
}

func (u *User) Auth(username, password string) bool {
	var count int64
	DB.Model(u).Where("username=? AND password=?", username, utils.Md5(password)).Count(&count)
	return count > 0
}
